﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Threading.Tasks;
using System.Web.Http.Dispatcher;

namespace Cypher.Core
{
 public class ServiceTypeResolver : IHttpControllerTypeResolver
	{
	 #region IHttpControllerTypeResolver Members

		public ICollection<Type> GetControllerTypes(IAssembliesResolver assembliesResolver)
		{
			if (assembliesResolver == null)
				throw new ArgumentNullException("assembliesResolver");


			List<Type> list = new List<Type>();
			ICollection<Assembly> assemblies = assembliesResolver.GetAssemblies();
			foreach (Assembly current in assemblies)
			{
				Type[] array = null;
				if (!(current == null) && !current.IsDynamic)
				{
					try
					{
						array = current.GetExportedTypes();
					}
					catch (ReflectionTypeLoadException ex)
					{
						array = ex.Types;
					}
					catch
					{
						continue;
					}
					if (array != null)
					{
						list.AddRange(
							from x in array
							where this.IsControllerTypePredicate(x)
							select x);
					}
				}
			}
			return list;
		}

		Predicate<Type> _isControllerTypePredicate;
		protected Predicate<Type> IsControllerTypePredicate
		{
			get
			{
				return this._isControllerTypePredicate;
			}
		}


		public ServiceTypeResolver(bool includeHttpControllers)
			: this(new Predicate<Type>(ServiceTypeResolver.IsControllerType), includeHttpControllers)
		{
		}
		/// <summary>Initializes a new <see cref="T:System.Web.Http.Dispatcher.DefaultHttpControllerTypeResolver" /> instance using a predicate to filter controller types. </summary>
		/// <param name="predicate">The predicate.</param>
		public ServiceTypeResolver(Predicate<Type> predicate, bool includeHttpControllers)
		{
			if (predicate == null)
			{
				throw new ArgumentNullException("predicate");
			}
			this._isControllerTypePredicate = predicate;
			ServiceTypeResolver.b = includeHttpControllers;
		}

		static bool b;

		internal static bool IsControllerType(Type t)
		{
			bool value = typeof(ICypherService).IsAssignableFrom(t);
			if (b)
			{
				value = typeof(System.Web.Http.Controllers.IHttpController).IsAssignableFrom(t);
			}

			return t != null && t.IsClass && t.IsPublic && !t.IsAbstract && value;
		}

		#endregion
	}
}
